﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

#endregion

namespace MetaHeuristics.Aco
{
    using MetaHeuristics.Tsp;

    public class AcoTspRenderer : TspRenderer
    {
        private AcoForTspAlgorithm aco;

        private Color minPheromoneColor = Color.FromArgb(200,Color.LightGray);
        private Color maxPheromoneColor = Color.OrangeRed;
        private Color antColor = Color.Red;

        [Category("Appearance")]
        public Color MinPheromoneColor
        {
            get
            {
                return minPheromoneColor;
            }

            set
            {
                minPheromoneColor = value;
            }
        }

        [Category("Appearance")]
        public Color MaxPheromoneColor
        {
            get
            {
                return maxPheromoneColor;
            }

            set
            {
                maxPheromoneColor = value;
            }
        }

        [Category("Appearance")]
        public Color AntColor
        {
            get
            {
                return antColor;
            }

            set
            {
                antColor = value;
            }
        }

        public AcoTspRenderer(AcoForTspAlgorithm aco)
            :base(aco.Tsp)
        {
            this.aco = aco;
        }

        public AcoForTspAlgorithm Aco
        {
            get
            {
                return this.aco;
            }
        }

        protected override void CustomRender(Graphics g)
        {
            this.RenderAnt(g,this.Aco.BestAnt);
        }

        protected virtual void RenderAnt(Graphics g, Ant ant)
        {
            Pen pen = this.CreateAntPen(g, ant);
            for (int i = 0; i < ant.Tours.Count-1; ++i)
            {
                g.DrawLine(
                    pen, 
                    this.Project(this.Aco.Tsp.Cities[ant.Tours[i]].Position),
                    this.Project(this.Aco.Tsp.Cities[ant.Tours[i + 1]].Position)
                    );
            }
        }

        protected override Pen CreateRoutePen(Graphics g, int i, int j)
        {
            // get pheromone color
            float pheromone = this.Aco.Pheromones.GetNormalized(i, j);
            Color c = ColorMath.Combine(this.MinPheromoneColor, pheromone, this.MaxPheromoneColor);
            Pen pen = new Pen(c, this.RouteWidth);
            return pen;
        }

        protected virtual Pen CreateAntPen(Graphics g, Ant ant)
        {
            Pen pen = new Pen(this.AntColor, this.RouteWidth + 1);
            pen.EndCap = LineCap.ArrowAnchor;
            return pen;
        }
    }
}
